我們知道軟體開發會經過一連串的活動, 如下面所示, 可分成需求分析, 架構設計, 詳細設計, 和開發編程. 在瀑布式開發中, 這些活動是依序被執行. 但是在敏捷開發中, 這些活動是混合在進行.
讓我們來看看這些活動要做什麼事情:
因為開發有這些活動, 為了確保這些活動的品質, 我們需要檢查他們有沒有做好, 因此我們產生這些測試階段, 一對一對應到開發這些活動.
圖 5-1 開發階段和測試階段
在進行這些測試時, 我們常常遭遇到一個問題, 測試人員在測試時, 有些狀況需要開發人員提供一些機制, 讓測試活動比較方便進行.
例如: 如何判斷功能執行結果, 需要產生一些 debug log, 或者是畫面需要顯示某些內容. 當我們要進行自動化測試, 我們可能也需要受測系統提供些 API, 讓我們可以方便操控受測軟體的運作, 或者是讀取受測系統的內部狀態.
這時候你會聽到開發人員說: 我們沒辦法加, 這些會需要改設計. 或者說這個需要時間做, 為什麼不早說. 等等種種說(藉)法(口).
因此, 根據前面開發階段和測試階段的圖形(如下圖 5-2 所示), 左半部的階段, 我們需要進行測試的設計, 把進行測試活動所需要的幫助, 提早跟開發人員說, 讓他們在開發前期就考慮進去. 像是開出一些測試要用的 API, 產生一些測試要確認的除錯資訊, 或是畫面上的資訊是否可以多顯示一些訊息.
所以當測試在執行時, 也就是圖 5-2 的右側, 測試人員會比較容易, 因為相關資訊或是會用到的介面已經準備好.
這些部分不是只有進行測試執行時有幫助. 當有 bug 發生, 開發人員需要除錯或者是要再次驗證, 這些機制也可以幫助到開發人員.
圖 5-2 在開發階段和測試階段有不同重點
另外, 你可能會聽到 Validation vs Verification, 但是因為我們不是外國人, 所以搞不清楚有什麼差別. 如果簡單說可以是以下兩句話:
Validation: do the right thing (做對事情)
Verification: do the thing right (把事情做對)
Validation 是要確認受測軟體是否能夠解決客戶的問題, 而 Verification 是否有按照規格書上面寫的去做.
所以根據圖 5-3 來看, 驗收測試就是屬於 Validation 的測試, 客戶或是測試人員要確認常用的場景, 受測軟體是否能夠解決問題. 而系統測試, 整合測試, 和單元測試, 則是確認開發人員是否照個需求規格書, 或是設計規格書上面所寫的去做, 這邊就算做得很完美, 有可能這不是客戶要的功能, 還是無法讓客戶接受.
圖 5-3 做對的事和把事做對
在每個階段都可能會找到錯誤, 但是在不同階段找到的問題, 他們修復的代價並不相同. 根據 Applied Software Measurement 一書的內容, 85%的錯誤是在 Coding 階段產生, 但是很少在這個階段就找到錯誤. 隨著測試的進行, unit test, function test 到 field test 找到錯誤的比例就越來越高, post release 階段因為沒有在測試, 所以就比較難找到問題.
可是對於錯誤修復要花費的代價, 在 coding 階段幾乎不用費用, 但是越到後面, 費用可能高達 1,000 到 16,000 美元左右的代價. 所以如果你可以越早找到問題, 所需的代價就越少.
圖 5-4 錯誤越早期發現, 代價越低
此外, 有人問到為什麼我們需要這麼多測試階段, 不能夠只進行單元測試就好, 有需要進行其他種類的測試階段嗎?
主要的原因是每個階段抓的錯誤都是不同類型, 並且只有那個階段容易抓得到. 例如下圖所示, FunB 以為 FunA 有兩個參數, 但是 FunA 只有一個, 分開各自測試可能都沒問題, 但是合起來才會發現有問題.
你或許會說這種介面個數不同, 應該不太可能發生, 一早就會知道, 或者邊一早就不過. 這或許沒錯. 另一種狀況是假設兩邊都是一個參數, 但是 FunB 認為 >3 的數值是有問題, 但是 FunA 認為只要不是 0 都沒問題, 對相同資料卻有不同解讀, 這種情況也很常見, 這也是各自測都沒問題, 要合在一起測試才有機會找出問題.
圖 5-5 寫 Fun B 的人不知道 寫 FunA 的人怎麼想
不禁想到汽車業使用的 V-model 方法論,不同階段對應到不同種類的測試。彷彿也像打高爾夫球一樣,開球就是要用木桿,求的是距離;上菓嶺就是要用推桿,求的是準確
文中有關的 $$ ,在不同行業或許有不同的數字,但在開發過程中,不管哪個行業,應該都是越晚發現,代價越高的吧